package com.jspgou.cms.action.front;

import static com.jspgou.cms.Constants.MEMBER_SYS;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.jspgou.cms.entity.Cart;
import com.jspgou.cms.entity.Order;
import com.jspgou.cms.entity.Payment;
import com.jspgou.cms.entity.Shipping;
import com.jspgou.cms.entity.ShopMember;
import com.jspgou.cms.manager.CartMng;
import com.jspgou.cms.manager.OrderMng;
import com.jspgou.cms.manager.PaymentMng;
import com.jspgou.cms.manager.ShippingMng;
import com.jspgou.cms.manager.ShopMemberAddressMng;
import com.jspgou.cms.manager.ShopMemberMng;
import com.jspgou.cms.service.ShoppingSvc;
import com.jspgou.cms.web.CmsUtils;
import com.jspgou.cms.web.ShopFrontHelper;
import com.jspgou.cms.web.SiteUtils;
import com.jspgou.common.security.annotation.Secured;
import com.jspgou.common.web.session.SessionProvider;
import com.jspgou.common.web.springmvc.MessageResolver;
import com.jspgou.core.entity.Website;
import com.jspgou.core.web.WebErrors;
import com.jspgou.core.web.front.FrontHelper;

@Secured
@Controller
public class ShoppingCartAct {
	private static final Logger log = LoggerFactory
			.getLogger(ShoppingCartAct.class);
	private static final String CHECKOUT_PAYMENT = "tpl.checkoutPayment";
	private static final String ORDER_COMPLETE = "tpl.orderComplete";



	@RequestMapping(value = "/checkout_shipping.jspx", method = RequestMethod.POST)
	public String shippingSubmit(Long shippingId, String redirectUrl,
			HttpServletRequest request, ModelMap model) {
		Website web = SiteUtils.getWeb(request);
		ShopMember member=CmsUtils.getMember(request);
		Cart cart = shoppingSvc.getCart(member.getId());
		if (cart == null) {
			return "redirect:shopping_cart.jspx";
		}
		WebErrors errors = validateShipping(shippingId, web, request);
		if (errors.hasErrors()) {
			return FrontHelper.showError(errors, web, model, request);
		}
		Shipping shipping = shippingMng.findById(shippingId);
		cartMng.update(cart);
		log.info("Member {} select ShoppingCart shipping: {}", member
				.getUsername(), shipping.getName());
		if (!StringUtils.isBlank(redirectUrl)) {
			return "redirect:" + redirectUrl;
		} else {
			return "redirect:checkout_payment.jspx";
		}
	}

	@RequestMapping(value = "/checkout_payment.jspx", method = RequestMethod.GET)
	public String paymentInput(String continueUrl, HttpServletRequest request,
			ModelMap model) {
		Website web = SiteUtils.getWeb(request);
		ShopMember member=CmsUtils.getMember(request);
		Cart cart = shoppingSvc.getCart(member.getId());
		if (cart == null) {
			return "redirect:shopping_cart.jspx";
		}
		List<Payment> paymentList = paymentMng.getListForCart(web.getId());
		model.addAttribute("cart", cart);
		model.addAttribute("paymentList", paymentList);
		if (!StringUtils.isBlank(continueUrl)) {
			model.addAttribute("continueUrl", continueUrl);
		}
		ShopFrontHelper.setCommonData(request, model, web);
		return web.getTplSys(MEMBER_SYS, MessageResolver.getMessage(request,
				CHECKOUT_PAYMENT), request);
	}

	@RequestMapping(value = "/checkout_payment.jspx", method = RequestMethod.POST)
	public String paymentSubmit(Long paymentId, String redirectUrl,
			HttpServletRequest request, ModelMap model) {
		Website web = SiteUtils.getWeb(request);
		ShopMember member=CmsUtils.getMember(request);
		Cart cart = shoppingSvc.getCart(member.getId());
		if (cart == null) {
			return "redirect:shopping_cart.jspx";
		}
		WebErrors errors = validatePayment(paymentId, web, request);
		if (errors.hasErrors()) {
			return FrontHelper.showError(errors, web, model, request);
		}
		Payment payment = paymentMng.findById(paymentId);
		cartMng.update(cart);
		log.info("Member {} select ShoppingCart payment: {}", member
				.getUsername(), payment.getName());
		if (!StringUtils.isBlank(redirectUrl)) {
			return "redirect:" + redirectUrl;
		} else {
			return "redirect:checkout_confirmation.jspx";
		}
	}

	

	@RequestMapping(value = "/order_success.jspx")
	public String orderSuccess(Long orderId, HttpServletRequest request,
			ModelMap model) {
		Website web = SiteUtils.getWeb(request);
		ShopMember member=CmsUtils.getMember(request);
		WebErrors errors = validateOrder(orderId, member.getId(), request);
		if (errors.hasErrors()) {
			return FrontHelper.showError(errors, web, model, request);
		}
		Order order = orderMng.findById(orderId);
		model.addAttribute("order", order);
		ShopFrontHelper.setCommonData(request, model, web);
		return web.getTplSys(MEMBER_SYS, MessageResolver.getMessage(request,
				ORDER_COMPLETE), request);
	}

	private WebErrors validateShipping(Long shippingId, Website web,
			HttpServletRequest request) {
		WebErrors errors = WebErrors.create(request);
		if (errors.ifNull(shippingId, "shippingId")) {
			return errors;
		}
		Shipping shipping = shippingMng.findById(shippingId);
		if (errors.ifNotExist(shipping, Shipping.class, shippingId)) {
			return errors;
		}
		if (!shipping.getWebsite().getId().equals(web.getId())) {
			errors.notInWeb(Shipping.class, shippingId);
			return errors;
		}
		return errors;
	}

	private WebErrors validatePayment(Long paymentId, Website web,
			HttpServletRequest request) {
		WebErrors errors = WebErrors.create(request);
		if (errors.ifNull(paymentId, "paymentId")) {
			return errors;
		}
		Payment payment = paymentMng.findById(paymentId);
		if (errors.ifNotExist(payment, Payment.class, paymentId)) {
			return errors;
		}
		if (!payment.getWebsite().getId().equals(web.getId())) {
			errors.notInWeb(Payment.class, paymentId);
			return errors;
		}
		return errors;
	}

	private WebErrors validateConfirmation(Cart cart, String comments,
			HttpServletRequest request) {
		WebErrors errors = WebErrors.create(request);
		if (errors.ifMaxLength(comments, "comments", 255)) {
			return errors;
		}
//		if (errors.ifNull(cart.getAddress(), "address")) {
//			return errors;
//		}
//		if (errors.ifNull(cart.getShipping(), "shipping")) {
//			return errors;
//		}
//		if (errors.ifNull(cart.getPayment(), "payment")) {
//			return errors;
//		}
		return errors;
	}

	private WebErrors validateOrder(Long orderId, Long memberId,
			HttpServletRequest request) {
		WebErrors errors = WebErrors.create(request);
		if (errors.ifNull(orderId, "orderId")) {
			return errors;
		}
		Order order = orderMng.findById(orderId);
		if (!order.getMember().getId().equals(memberId)) {
			errors.addErrorCode("error.noPermission", Order.class, orderId);
			return errors;
		}
		return errors;
	}

	private String checkConfirmation(Cart cart) {
		if (cart == null) {
			return "redirect:shopping_cart.jspx";
		}
//		if (cart.getAddress() == null) {
//			return "redirect:checkout_address.jspx";
//		}
//		if (cart.getShipping() == null) {
//			return "redirect:checkout_shipping.jspx";
//		}
//		if (cart.getPayment() == null) {
//			return "redirect:checkout_payment.jspx";
//		}
		return null;
	}

	@Autowired
	private OrderMng orderMng;
	@Autowired
	private ShoppingSvc shoppingSvc;
	@Autowired
	private ShippingMng shippingMng;
	@Autowired
	private PaymentMng paymentMng;
	@Autowired
	private ShopMemberAddressMng shopMemberAddressMng;

	@Autowired
	private CartMng cartMng;
	@Autowired
	private ShopMemberMng memberMng;
	@Autowired
	private SessionProvider session;
}
